﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net.Sockets;

namespace SLClient
{
    public class PointEventArgs : EventArgs
    {
        public Point Point { get; set; }
    }

    public class Communication
    {
        public event EventHandler<PointEventArgs> PointReceived;

        public Communication()
        {
            this.buffer = new byte[16];
            this.socket = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            SocketAsyncEventArgs args = new SocketAsyncEventArgs() 
            {
                SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Tcp,
                RemoteEndPoint = new DnsEndPoint("localhost", 4530)
            };

            args.Completed+=OnConnected;
            this.socket.ConnectAsync(args);
        }

        void OnConnected(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError != SocketError.Success)
            {
                socket = null;
            }
            else
            {
                BeginRead();
            }
        }

        void BeginRead()
        {
            if (this.socket!=null)
            {
                SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                args.SetBuffer(buffer, bytesReceived, buffer.Length - bytesReceived);
                args.Completed += OnReadCompleted;

                this.socket.ReceiveAsync(args);

            }
        }

        void OnReadCompleted(object sender, SocketAsyncEventArgs e)
        {
            this.bytesReceived += e.BytesTransferred;
            if (this.bytesReceived==this.buffer.Length)
            {
                Point p = PointExt.FromBuffer(this.buffer);
                if (PointReceived!=null)
                {
                    PointReceived(this, new PointEventArgs()
                    {
                        Point = p
                    });
                }
                this.bytesReceived = 0;
            }
            BeginRead();
        }

        /// <summary>
        /// Notifica il server che poi notifica tutti i clients
        /// </summary>
        /// <param name="point"></param>
        internal void SendPoint(Point point)
        {
            if (this.socket!=null)
            {
                byte[] bits = PointExt.ToBuffer(point);
                SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                args.SetBuffer(bits, 0, bits.Length);
                //handle completedEvent
                //args.Completed+=OnSendCompleted;
                this.socket.SendAsync(args);
            }
        }

        //void OnSendCompleted(Object sender, SocketAsyncEventArgs e )
        //{

        //}

        int bytesReceived;
        byte[] buffer;
        Socket socket;

    }
}
